home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / mail / delivery / smail-3.1 / smail-3
Text File  |  1994-12-13  |  13KB  |  437 lines

  1. --- src/smtprecv.c    1994/11/30 08:44:04    1.2
  2. +++ src/smtprecv.c    1994/11/30 15:10:34    1.3
  3. @@ -1,4 +1,4 @@
  4. -/* @(#) $Id: smtprecv.c,v 1.2 1994/11/30 08:44:04 logiciel Exp $ */
  5. +/* @(#) $Id: smtprecv.c,v 1.3 1994/11/30 15:10:34 logiciel Exp $ */
  6.  
  7.  /*
  8.   *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  9. @@ -279,7 +279,9 @@
  10.          if (out) {
  11.          fprintf(out, "250-%s Hello %s, here's what we support:\r\n",
  12.              primary_name, data);
  13. +#ifndef NO_VERIFY
  14.          fprintf(out, "250-EXPN\r\n");
  15. +#endif
  16.  #ifdef HAVE_DF_SPOOL
  17.          accepted_msg_size = compute_max_message_size_from_df_spool ();
  18.          if (accepted_msg_size == -1 
  19. --- src/transports/smtplib.c    1994/11/30 08:58:18    1.2
  20. +++ src/transports/smtplib.c    1994/12/13 11:39:28    1.5
  21. @@ -1,4 +1,4 @@
  22. -/* @(#) $Id: smtplib.c,v 1.2 1994/11/30 08:58:18 logiciel Exp $ */
  23. +/* @(#) $Id: smtplib.c,v 1.5 1994/12/13 11:39:28 logiciel Exp $ */
  24.  
  25.  /*
  26.   *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  27. @@ -52,8 +52,10 @@
  28.  #define DATA        "DATA"
  29.  #define DATA_END    "."
  30.  #define QUIT        "QUIT"
  31. +#define VERB        "VERB"
  32.  
  33.  /* reply code groups, encoded in hex */
  34. +#define POSITIVE_DEBUG        0x000    /* debugging messages */
  35.  #define POSITIVE_PRELIM        0x100    /* positive preliminary replies */
  36.  #define POSITIVE_COMPLETE    0x200    /* positive completion replies */
  37.  #define POSITIVE_INTERMEDIATE    0x300    /* positive intermediate replies */
  38. @@ -84,7 +86,7 @@
  39.  
  40.  /* functions local to this file */
  41.  #ifdef __STDC__
  42. -extern int smtp_startup(struct smtp *, struct error **);
  43. +extern int smtp_startup(struct smtp *, struct error **, int);
  44.  extern int smtp_send(struct smtp *, struct addr *, struct addr **, struct addr **, struct addr **, struct error **);
  45.  extern void smtp_shutdown(struct smtp *);
  46.  static void do_smtp_shutdown(struct smtp *, int);
  47. @@ -130,17 +132,25 @@
  48.   * the session for future mail commands.  Once the startup has been
  49.   * acomplished, smtp_send() can be used to send individual messages.
  50.   *
  51. + * If try_ehlo is non-zero and ESMTP support is configured, perform
  52. + * ESMTP negotiaition using the EHLO greeting command.
  53. + *
  54.   * return:
  55.   *    SMTP_SUCCEED on successful startup
  56.   *    SMTP_FAIL if the connection should not be retried
  57.   *    SMTP_AGAIN if the connection should be retried later
  58. + *    SMTP_EHLO_FAIL if the receiver hung up in response
  59. + *        to an EHLO command.  This can only occur when
  60. + *        try_ehlo is set.
  61.   *
  62. - * For SMTP_FAIL and SMTP_AGAIN, return a filled-in error structure.
  63. + * For SMTP_FAIL and SMTP_AGAIN (but not SMTP_EHLO_FAIL), return a
  64. + * filled-in error structure.
  65.   */
  66.  int
  67. -smtp_startup(smtpb, error_p)
  68. +smtp_startup(smtpb, error_p, try_ehlo)
  69.      struct smtp *smtpb;            /* SMTP description block */
  70.      struct error **error_p;        /* error description */
  71. +    int try_ehlo;            /* whether to use ESMTP */
  72.  {
  73.      int reply;
  74.      char *reply_text;
  75. @@ -171,101 +181,133 @@
  76.      }
  77.  
  78.  #ifdef HAVE_EHLO
  79. -    /*
  80. -     * say who we are.
  81. -     * Possible responses:
  82. -     *    250 - okay        (continue conversation)
  83. -     *    421 - closing down  (try again later)
  84. -     *  5xx - fatal error   (try HELO)
  85. -     */
  86. -    smtp_out.i = 0;
  87. -    (void) str_printf(&smtp_out, EHLO(primary_name));
  88. +    if (try_ehlo) {
  89. +    /*
  90. +     * say who we are.
  91. +     * Possible responses:
  92. +     *    250 - okay        (continue conversation)
  93. +     *    421 - closing down  (try again later)
  94. +     *  5xx - fatal error   (try HELO)
  95. +     */
  96. +    smtp_out.i = 0;
  97. +    (void) str_printf(&smtp_out, EHLO(primary_name));
  98.  
  99. -    reply = wait_write_command(smtpb, smtpb->short_timeout,
  100. -                   smtp_out.p, smtp_out.i, &reply_text);
  101. +    reply = wait_write_command(smtpb, smtpb->short_timeout,
  102. +                   smtp_out.p, smtp_out.i, &reply_text);
  103.  
  104. -    if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) {
  105. -    /* remote SMTP closed, try again later */
  106. -    *error_p = try_again(smtpb->tp, reply_text);
  107. -    return SMTP_AGAIN;
  108. -    }
  109. -    if (reply == REPLY_OK) {
  110. -    char * cp = reply_text;
  111. -    int on_greet_line = 1;
  112. -
  113. -    smtpb->smtp_flags = ESMTP_basic;
  114. -    /* Parse the EHLO reply to find out
  115. -       what the remote server supports */
  116. -    while (*cp != 0) {
  117. -        int skip;
  118. -        int keywordlength;
  119. -
  120. -        for (skip = 4; *cp != 0 && skip; --skip, ++cp) {
  121. -        if (skip == 1
  122. -            ? (*cp != ' ' && *cp != '-')
  123. -            : (! isdigit (*cp))) {
  124. +    if (reply == REPLY_TIMEOUT) {
  125. +        /* Some gateways just terminate the conection when they
  126. +           receive an EHLO.  We handle this case by returning a
  127. +           special value here.  Also write a message to the log
  128. +           file because it is interesting to know which mailers
  129. +           expose this problem. */
  130. +        write_log(LOG_SYS, "link broken by EHLO!");
  131. +        return SMTP_EHLO_FAIL;
  132. +    }
  133. +    if (REPLY_GROUP(reply) == NEGATIVE_TRY_AGAIN) {
  134. +        /* remote SMTP closed, try again later */
  135. +        *error_p = try_again(smtpb->tp, reply_text);
  136. +        return SMTP_AGAIN;
  137. +    }
  138. +    if (reply == REPLY_OK) {
  139. +        char * cp = reply_text;
  140. +        int on_greet_line = 1;
  141. +
  142. +        smtpb->smtp_flags = ESMTP_basic;
  143. +        /* Parse the EHLO reply to find out
  144. +           what the remote server supports */
  145. +        while (*cp != 0) {
  146. +        int skip;
  147. +        int keywordlength;
  148. +
  149. +        for (skip = 4; *cp != 0 && skip; --skip, ++cp) {
  150. +            if (skip == 1
  151. +            ? (*cp != ' ' && *cp != '-')
  152. +            : (! isdigit (*cp))) {
  153. +            goto malformed_ehlo_reply;
  154. +            }
  155. +        }
  156. +        if (skip != 0) {
  157.              goto malformed_ehlo_reply;
  158.          }
  159. -        }
  160. -        if (skip != 0) {
  161. -        goto malformed_ehlo_reply;
  162. -        }
  163. -        if (on_greet_line) {
  164. -        /*
  165. -         * Ignore greeting on first line
  166. -         */
  167. -        on_greet_line = 0;
  168. -        goto skip_rest_of_line;
  169. -        }
  170. -        for (keywordlength = 0;
  171. -         *(cp+keywordlength) != 0
  172. -         && !isspace (*(cp+keywordlength));
  173. -         ++keywordlength)
  174. -        ;
  175. -        if (strncmpic(cp, "SIZE", keywordlength) == 0) {
  176. -        unsigned long max_size = 0;
  177. -
  178. -        cp += keywordlength;
  179. -        while (*cp == ' ' || *cp == '\t')
  180. -        ++cp;
  181. -        if (!isdigit(*cp) && *cp != '\n')
  182. -        goto malformed_ehlo_reply;
  183. -        while (isdigit(*cp)) {
  184. -            max_size *= 10;
  185. -            max_size += *cp - '0';
  186. -            ++cp;
  187. +        if (on_greet_line) {
  188. +            /*
  189. +             * Ignore greeting on first line
  190. +             */
  191. +            on_greet_line = 0;
  192. +            goto skip_rest_of_line;
  193.          }
  194. -        smtpb->smtp_flags |= ESMTP_size;
  195. -        smtpb->max_size = max_size;
  196. -        } else if (strncmpic(cp, "8BITMIME", keywordlength) == 0) {
  197. -        smtpb->smtp_flags |= ESMTP_8bitmime;
  198. -        } else if (strncmpic(cp, "PIPELINING", keywordlength) == 0) {
  199. -        smtpb->smtp_flags |= ESMTP_pipelining;
  200. -        } else {
  201. +        for (keywordlength = 0;
  202. +             *(cp+keywordlength) != 0
  203. +             && !isspace (*(cp+keywordlength));
  204. +             ++keywordlength)
  205. +            ;
  206. +        if (strncmpic(cp, "SIZE", keywordlength) == 0) {
  207. +            unsigned long max_size = 0;
  208. +
  209. +            cp += keywordlength;
  210. +            while (*cp == ' ' || *cp == '\t')
  211. +            ++cp;
  212. +            if (!isdigit(*cp) && *cp != '\n')
  213. +            goto malformed_ehlo_reply;
  214. +            while (isdigit(*cp)) {
  215. +            max_size *= 10;
  216. +            max_size += *cp - '0';
  217. +            ++cp;
  218. +            }
  219. +            smtpb->smtp_flags |= ESMTP_size;
  220. +            smtpb->max_size = max_size;
  221. +        } else if (strncmpic(cp, "8BITMIME", keywordlength) == 0) {
  222. +            smtpb->smtp_flags |= ESMTP_8bitmime;
  223. +        } else if (strncmpic(cp, "PIPELINING", keywordlength) == 0) {
  224. +            smtpb->smtp_flags |= ESMTP_pipelining;
  225. +        } else if (strncmpic(cp, "XVRB", keywordlength) == 0) {
  226. +            smtpb->smtp_flags |= ESMTP_verbose;
  227. +        } else if (strncmpic(cp, "XONE", keywordlength) == 0) {
  228. +            smtpb->smtp_flags |= ESMTP_one;
  229. +        } else if (strncmpic(cp, "XQUE", keywordlength) == 0) {
  230. +            smtpb->smtp_flags |= ESMTP_queue;
  231. +        } else {
  232. +        }
  233. +          skip_rest_of_line:
  234. +        while (*cp != 0 && *cp != '\n')
  235. +            ++cp;
  236. +        if (*cp == '\n')
  237. +            ++cp;
  238.          }
  239. -      skip_rest_of_line:
  240. -        while (*cp != 0 && *cp != '\n')
  241. -        ++cp;
  242. -        if (*cp == '\n')
  243. -        ++cp;
  244. -    }
  245.  #ifndef NO_LOG_EHLO
  246. -    write_log(LOG_SYS, "destination supports esmtp%s%s%s",
  247. -          smtpb->smtp_flags & ESMTP_8bitmime ? " 8BITMIME" : "",
  248. -          smtpb->smtp_flags & ESMTP_size ? " SIZE" : "",
  249. -          smtpb->smtp_flags & ESMTP_pipelining ? " PIPELINING" : "");
  250. +        write_log(LOG_SYS, "destination supports esmtp%s%s%s%s%s%s",
  251. +              smtpb->smtp_flags & ESMTP_8bitmime ? " 8BITMIME" : "",
  252. +              smtpb->smtp_flags & ESMTP_size ? " SIZE" : "",
  253. +              smtpb->smtp_flags & ESMTP_pipelining ? " PIPELINING" : "",
  254. +              smtpb->smtp_flags & ESMTP_verbose ? " XVRB" : "",
  255. +              smtpb->smtp_flags & ESMTP_one ? " XONE" : "",
  256. +              smtpb->smtp_flags & ESMTP_queue ? " XQUE" : "");
  257.  #endif /* not NO_LOG_EHLO */
  258. -    return SMTP_SUCCEED;
  259. -      malformed_ehlo_reply:
  260. -    /* This seems to be a reasonable way
  261. -       to handle malformed EHLO replies: */
  262. +        if (smtpb->smtp_flags & ESMTP_verbose
  263. +        && debug >= DBG_DRIVER_MID) {
  264. +        smtp_out.i = 0;
  265. +        (void) str_printf(&smtp_out, VERB);
  266. +        reply = wait_write_command(smtpb, smtpb->short_timeout,
  267. +                       smtp_out.p, smtp_out.i, &reply_text);
  268. +        if (REPLY_GROUP (reply) == NEGATIVE_TRY_AGAIN) {
  269. +            /* remote SMTP closed, try again later */
  270. +            *error_p = try_again(smtpb->tp, reply_text);
  271. +            return SMTP_AGAIN;
  272. +        }
  273. +        }
  274. +        return SMTP_SUCCEED;
  275. +      malformed_ehlo_reply:
  276. +        /* This seems to be a reasonable way
  277. +           to handle malformed EHLO replies: */
  278.  #ifndef NO_LOG_EHLO
  279. -    write_log(LOG_SYS, "destination supports esmtp, but is buggy (%s)",
  280. -          reply_text);
  281. +        write_log(LOG_SYS, "destination supports esmtp, but is buggy (%s)",
  282. +              reply_text);
  283.  #endif /* not NO_LOG_EHLO */
  284. -    return SMTP_SUCCEED;
  285. +        return SMTP_SUCCEED;
  286. +    }
  287.      }
  288. -#endif
  289. +#endif /* HAVE_EHLO */
  290.      /*
  291.       * say who we are.
  292.       * Possible responses:
  293. @@ -755,8 +797,12 @@
  294.      if (! smtpb->in) {
  295.      return REPLY_OK;
  296.      }
  297. -    result = read_response_internal (smtpb, timeout, reply_text);
  298. -    DEBUG1(DBG_DRIVER_MID, "SMTP-reply: %s\n", *reply_text);
  299. +    do
  300. +      {
  301. +    result = read_response_internal (smtpb, timeout, reply_text);
  302. +    DEBUG1(DBG_DRIVER_MID, "SMTP-reply: %s\n", *reply_text);
  303. +      }
  304. +    while (REPLY_GROUP (result) == POSITIVE_DEBUG);
  305.      return result;
  306.  }
  307.  
  308. --- src/transports/smtplib.h    1994/11/30 08:59:35    1.2
  309. +++ src/transports/smtplib.h    1994/12/13 10:59:53    1.4
  310. @@ -1,4 +1,4 @@
  311. -/* @(#) $Id: smtplib.h,v 1.2 1994/11/30 08:59:35 logiciel Exp $ */
  312. +/* @(#) $Id: smtplib.h,v 1.4 1994/12/13 10:59:53 logiciel Exp $ */
  313.  
  314.  /*
  315.   *    Copyright (C) 1987, 1988 by Ronald S. Karr and Landon Curt Noll
  316. @@ -17,6 +17,7 @@
  317.  #define SMTP_SUCCEED    0
  318.  #define SMTP_FAIL    (-1)
  319.  #define SMTP_AGAIN    (-2)
  320. +#define SMTP_EHLO_FAIL    (-3)
  321.  
  322.  typedef enum
  323.  {
  324. @@ -24,7 +25,10 @@
  325.      ESMTP_basic        = 0x0001,
  326.      ESMTP_8bitmime    = 0x0002,
  327.      ESMTP_size        = 0x0004,
  328. -    ESMTP_pipelining    = 0x0008
  329. +    ESMTP_pipelining    = 0x0008,
  330. +    ESMTP_verbose    = 0x0010,
  331. +    ESMTP_one        = 0x0020,
  332. +    ESMTP_queue        = 0x0040
  333.  }
  334.  SMTPExtension, SMTPExtensionFlags;
  335.  
  336. --- src/transports/tcpsmtp.c    1994/11/30 09:04:54    1.2
  337. +++ src/transports/tcpsmtp.c    1994/12/13 11:41:04    1.3
  338. @@ -288,6 +288,7 @@
  339.      char *error_text;
  340.      int success;
  341.      struct addr *ap;
  342. +    int try_ehlo;
  343.  
  344.      priv = (struct tcpsmtp_private *)tp->private;
  345.  
  346. @@ -310,43 +311,53 @@
  347.  
  348.      /* reach out and touch someone */
  349.  
  350. -    s = tcpsmtp_connect(hostname, ipaddr, family, service, &error_text);
  351. -    if (s >= 0) {
  352. -        s2 = dup(s);
  353. -        if (s2 < 0) {
  354. -            (void) close(s);
  355. -            s = -1;
  356. -        }
  357. -    }
  358. -    if (s < 0) {
  359. -        *ep = connect_failure(tp, error_text);
  360. -        return SMTP_AGAIN;
  361. -    }
  362. -
  363. -    smtpbuf.in = fdopen(s, "r");
  364. -    smtpbuf.out = fdopen(s2, "w");
  365. -    smtpbuf.short_timeout = priv->short_timeout;
  366. -    smtpbuf.long_timeout = priv->long_timeout;
  367. -    smtpbuf.nl = "\r\n";
  368. -    tp->flags |= PUT_CRLF;
  369. -    smtpbuf.tp = tp;
  370. -    smtpbuf.smtp_flags = ESMTP_none;
  371. -    smtpbuf.max_size = 0;
  372. -
  373. -    DEBUG(DBG_DRIVER_LO, "connected\n");
  374. -
  375. -    switch (smtp_startup(&smtpbuf, ep)) {
  376. -
  377. -    case SMTP_FAIL:
  378. -        insert_addr_list(addr, fail, *ep);
  379. -        (void) fclose(smtpbuf.in);
  380. -        (void) fclose(smtpbuf.out);
  381. -        return SMTP_FAIL;
  382. -
  383. -    case SMTP_AGAIN:
  384. -        (void) fclose(smtpbuf.in);
  385. -        (void) fclose(smtpbuf.out);
  386. -        return SMTP_AGAIN;
  387. +    for (try_ehlo = 1, success = 0; !success && try_ehlo >= 0; --try_ehlo) {
  388. +    s = tcpsmtp_connect(hostname, ipaddr, family, service, &error_text);
  389. +    if (s >= 0) {
  390. +        s2 = dup(s);
  391. +        if (s2 < 0) {
  392. +        (void) close(s);
  393. +        s = -1;
  394. +        }
  395. +    }
  396. +    if (s < 0) {
  397. +        *ep = connect_failure(tp, error_text);
  398. +        return SMTP_AGAIN;
  399. +    }
  400. +
  401. +    smtpbuf.in = fdopen(s, "r");
  402. +    smtpbuf.out = fdopen(s2, "w");
  403. +    smtpbuf.short_timeout = priv->short_timeout;
  404. +    smtpbuf.long_timeout = priv->long_timeout;
  405. +    smtpbuf.nl = "\r\n";
  406. +    tp->flags |= PUT_CRLF;
  407. +    smtpbuf.tp = tp;
  408. +    smtpbuf.smtp_flags = ESMTP_none;
  409. +    smtpbuf.max_size = 0;
  410. +
  411. +    DEBUG(DBG_DRIVER_LO, "connected\n");
  412. +
  413. +    switch (smtp_startup(&smtpbuf, ep, try_ehlo)) {
  414. +
  415. +      case SMTP_FAIL:
  416. +        insert_addr_list(addr, fail, *ep);
  417. +        (void) fclose(smtpbuf.in);
  418. +        (void) fclose(smtpbuf.out);
  419. +        return SMTP_FAIL;
  420. +
  421. +      case SMTP_AGAIN:
  422. +        (void) fclose(smtpbuf.in);
  423. +        (void) fclose(smtpbuf.out);
  424. +        return SMTP_AGAIN;
  425. +
  426. +      case SMTP_EHLO_FAIL:
  427. +        (void) fclose(smtpbuf.in);
  428. +        (void) fclose(smtpbuf.out);
  429. +        break;
  430. +
  431. +      default:
  432. +        success = 1;
  433. +    }
  434.      }
  435.  
  436.      if (dont_deliver) {
  437.